package com.sanyue.springboot.controller;

import com.sanyue.springboot.bean.Monster;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * @author: Guan
 **/
// @RestController
@Controller//因为@RequestAttribute使用二次转发，需要通过视图解析器，需要注销掉RequestBody功能
public class ParameterController {
    /**
     * /monster/{id}/{name} 解读
     * 1. /monster/{id}/{name} 构成完整请求路径
     * 2. {id} {name} 就是占位变量
     * 3. @PathVariable("name"): 这里name 和{name} 命名保持一致
     * 4. String name_ 这里自定义，老师故意这样写下
     * 5. @PathVariable Map<String, String> map 把所有传递的值传入map
     *    map = {name=king, id=100}
     * 6. 可以看下@PathVariable源码
     */
    @GetMapping("/monster/{name}/{id}")
    public String pathVariable(@PathVariable("name")String name,
                               @PathVariable("id")Integer id, @PathVariable Map<String,String> map){

        System.out.println("name = " + name);
        System.out.println("id = " + id);
        System.out.println("map = " + map);
        return "success";
    }

    /**
     *
     * 解读：
     *  1.@RequestHeader获取请求头信息
     *  2，@RequestHeader("Host") String host：获取请求头host的信息
     *     2.1 @RequestHeader("Host")，@RequestHeader中的value值大小写无差别
     *     2.2 String host：名字程序员自定义
     *  3.@RequestHeader Map<String,String> header：获取到http请求头的所有信息
     * @param host
     * @param header
     * @return
     */
    @RequestMapping("/requestHeader")
    public String requestHeader(@RequestHeader("Host") String host,
                                @RequestHeader Map<String,String> header){
        System.out.println("host = " + host);
        System.out.println("header = " + header);
        return "success";
    }

    /**
     *
     * 内容：@RequestParam：获取请求参数
     * 解读：
     *  1.@RequestParam(value = "name",required = true) String username
     *    1.1 @RequestParam(value = "name"：获取参数名为name的值
     *    1.2 required = true，不允许不传入该属性的值，即可以不填写该属性会报错
     *        required = false，即使没有传入该属性，也不会报错，值为null
     *  2.@RequestParam("fruit")List<String>fruits：当一个属性有多个值的时候用List数组接收
     *  3.@RequestParam Map<String,String> paras：可以用Map集合接收所有数据
     *    注意：这样写有一个小问题，当一个值为数组类型（有多个数据的时候），只能接收第一个数据
     *    原因：因为Map的泛型为<String,String>，获取的值是唯一的，不能接收数组或集合类型
     * @param username
     * @param fruits
     * @return
     */
    @RequestMapping("/requestParam")
    public String requestParam(@RequestParam(value = "name",required = true) String username,
                               @RequestParam("fruit")List<String>fruits,
                               @RequestParam Map<String,String> paras){
        System.out.println("username = " + username);
        System.out.println("fruits = " + fruits);
        System.out.println("paras = " + paras);
        return "success";
    }


    /**
     * 内容：获取cookie数据
     * 解读：
     *  1.配置环境：我们在浏览器自己添加cookie，右键检查，在存储中添加（也可能在application）
     *  2.@CookieValue(value = "cookie_key",required = false) String cookie_value
     *    2.1 获取名字为cookie_key的Cookie的value值
     *    2.2 String cookie_value，如果注解修饰的类型为String，则获取的是Cookie对应的value值
     *  3.@CookieValue(value = "username",required = false)Cookie userCookie)
     *   3.1 获取名字为username的Cookie对象
     *   3.2 Cookie userCookie，如果注解修饰的类型为Cookie，则获取的是Cookie对象
     *  4.required = false：参数是否必须传入，同@RequestParam
     *  5.也可以通过HttpServletRequest获取cookie
     * @param cookie_value
     * @param userCookie
     * @return
     */
    @RequestMapping("/cookieValue")
    public String cookieValue(@CookieValue(value = "cookie_key",required = false) String cookie_value,
                              @CookieValue(value = "username",required = false)Cookie userCookie,
                              HttpServletRequest request){
        System.out.println("cookie_value = " + cookie_value);
        System.out.println("userCookie = " + userCookie);
        System.out.println("userCookie.getName() = " + userCookie.getName());
        System.out.println("userCookie.getValue() = " + userCookie.getValue());
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            System.out.println("cookie = " + cookie);
        }
        return "success";
    }


    /**
     * 内容：@RequestBody 获取post请求的请求数据
     *      在SpringMVC我们学过@RequestBody处理json数据
     * @param content
     * @return
     */
    @RequestMapping("/requestBody")
    public String requestBody(@RequestBody String content){
        System.out.println("content = " + content);
        return "success";
    }


    /**
     *  注解：
     *    1.@RequestAttribute——获取请求域中的数据
     *    2.@SessionAttribute——获取回话域中的数据
     *  内容：
     *    1.先请求login，在对应方法中设置请求域数据。
     *    2.再通过请求转发跳转ok
     *    3.在ok请求对应方法中，输出自己设置的请求域的数据
     *  解读：
     *    1.required = true：如果没有该数据，就报错（同以前学的）
     *  补充：同样也可以通过HttpServletRequest获取资源
     */
    @RequestMapping("/login")
    public String login(HttpServletRequest request){
        request.setAttribute("user","gpy");
        request.getSession().setAttribute("password","123456");
        return "forward:requestAttribute";
    }

    @ResponseBody
    @RequestMapping("/requestAttribute")
    public String requestAttribute(@RequestAttribute(value = "user",required = false) String user,
                                   @SessionAttribute(value = "password",required = true) String password,
                                   HttpServletRequest request){
        //通过注解方式获取请求域资源
        System.out.println("user = " + user);
        //通过原生HttpServletRequest获取资源
        Object user1 = request.getAttribute("user");
        System.out.println("user1 = " + user1);
        //通过注解方式获取Session资源
        System.out.println("password = " + password);
        return "success";
    }

    /**
     * 复杂参数问题
     * 内容：处理添加monster的方法
     * 解读：
     *   1.级联映射：
     *      Monster中有Car类的对象做为其中一个属性
     *      Car类中有name，price俩个属性
     *      当获取前端数据填充monster对象时，car对象的属性也会被填充
     * @return
     */
    @ResponseBody
    @PostMapping("/saveMonster")
    public String saveMonster(Monster monster){
        System.out.println("monster = " + monster);
        //SpringBoot中只允许get方式请求静态资源
        //所以如果转发会报错Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
        //因为SpringBoot已经默认前后端分离方式处理页面导致的
//        解决方案：
//        1.使用重定向方式跳转静态页面：return new ModelAndView("redirect:xxx.html");
        return "success";
    }
}
